/******* 第一题 *******/
class People {
    constructor(name) {
        this.name = name
        this.events = {};
    }
    // TODO: 请在此处完善代码
    on(event, callBack) {
        let eventArr = this.events[event] || (this.events[event] = []);
        eventArr.push(callBack);
    }
    off(event, callBack) {
        let eventArr = this.events[event];
        //判断要解除的事件是否存在
        if (eventArr) {
            //利用some，只要一解除了事件马上终止，避免过多循环。
            eventArr.some((item, index, arr) => {
                if (item === callBack) {
                    arr.splice(index, 1);
                    return true;
                }
            });
        } else {
            console.log('你要解除的事件不存在！');
        }
    }
    emit(event, data) {
        let eventArr = this.events[event];
        //判断要触发的事件是否存在
        if (eventArr) {
            eventArr.forEach(callBack => {
                callBack(data);
            })
        } else {
            console.log('你要触发的事件不存在！');
        }
    }
    sayHi() {
        console.log(`Hi, I am ${this.name}`)
    }
}


/* 以下为测试代码 */
const say1 = (greeting) => {
    console.log(`${greeting}, nice meeting you.`)
}

const say2 = (greeting) => {
    console.log(`${greeting}, nice meeting you, too.`)
}

const jerry = new People('Jerry')
jerry.sayHi()
// => 输出：'Hi, I am Jerry'

jerry.on('greeting', say1)
jerry.on('greeting', say2)

jerry.emit('greeting', 'Hi')
// => 输出：'Hi, nice meeting you.' 和 'Hi, nice meeting you, too'

jerry.off('greeting', say1)
jerry.emit('greeting', 'Hi')
// => 只输出：'Hi, nice meeting you, too'


/******* 第二题 *******/
const sleep = (duration) => {
    // TODO
    return new Promise((resovle) => {
        setTimeout(() => {
            resovle();
        }, duration);
    })
}

const anyFunc = async () => {
    console.log("123") // 输出 123
    await sleep(300) // 暂停 300 毫秒
    console.log("456") // 输出 456，但是距离上面输出的 123 时间上相隔了 300 毫秒
}
anyFunc();


/******* 第三题 *******/
const convert = (num) => {
    // TODO: 请在此处完善代码
    // A => 65
    let letter = '';
    while (num) {
        let time = num % 26;
        if (!time) {
            time = 26;
            num--;
        }
        num = parseInt(num / 26);
        letter = String.fromCodePoint(time + 64) + letter;
    }
    return letter;
}
// console.log(convert(26), convert(53));


/******* 第四题 *******/
const combo = (...fnArr) => {
    // TODO: 请在此处完善代码
    fnArr.reverse();
    let execute = (num) => {
        fnArr.reduce((prev, curr) => {
            // console.log(curr(prev));
            /***最后一个函数执行了,为什么返回值拿不到，我懵逼了，大神请告诉我。qq：346551572***/
            return curr(prev);
        }, num)
    }
    return execute;
}

/* 以下为测试代码 */
const addOne = (a) => a + 1
const multiTwo = (a) => a * 2
const divThree = (a) => a / 3
const toString = (a) => a + ''
const split = (a) => a.split('')

split(toString(addOne(multiTwo(divThree(666)))));
// => ["4", "4", "5"]

const testForCombo = combo(split, toString, addOne, multiTwo, divThree)
testForCombo(666);

// => ["4", "4", "5"]


/******* 第五题 *******/
/*   
    后手者有必胜策略
    条件一：后手者在两个球盘都不少于或等于两个球时，保持自身取球后球盘相加为偶数。
    条件二：当某个球盘数量等于二时，取另一球盘的总数减一（剩一个）；当某个球盘数量等于一时，取另一球盘全部球。
*/